package com.hoki.zj.hrm.service.impl;

import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.hoki.zj.hrm.asserts.GlobalAssert;
import com.hoki.zj.hrm.client.AuthServiceClient;
import com.hoki.zj.hrm.domain.LoginUser;
import com.hoki.zj.hrm.domain.VipBase;
import com.hoki.zj.hrm.domain.VipUser;
import com.hoki.zj.hrm.dto.MobileRegistryDto;
import com.hoki.zj.hrm.dto.SMSCodeValueInRedisDto;
import com.hoki.zj.hrm.exception.GlobalException;
import com.hoki.zj.hrm.mapper.VipBaseMapper;
import com.hoki.zj.hrm.mapper.VipUserMapper;
import com.hoki.zj.hrm.service.IVipUserService;
import com.hoki.zj.hrm.utils.AjaxResult;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;

/**
 * <p>
 * 会员登录账号 服务实现类
 * </p>
 *
 * @author shukei
 * @since 2021-09-20
 */
@Service
public class VipUserServiceImpl extends ServiceImpl<VipUserMapper, VipUser> implements IVipUserService {

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @Autowired
    private VipBaseMapper vipBaseMapper;

    @Autowired
    private AuthServiceClient authServiceClient;

    @Autowired
    private VipUserMapper vipUserMapper;

    // 用户类型: 前台用户
    private static final Integer USER_IN_FRONT = 0;

    /**
     * 前台用户手机注册
     * @param dto dto: mobile,password,smsCode,regChannel
     */
    @Override
    // @Transactional
    @GlobalTransactional // 全局事务注解
    public void registry(MobileRegistryDto dto) {
        String mobile = dto.getMobile();
        String password = dto.getPassword();
        String smsCode = dto.getSmsCode();
        String codeType = dto.getCodeType();
        Integer regChannel = dto.getRegChannel();
        // 1.判断参数
        checkParam(mobile, password, smsCode);
        // 2.判断手机号是否已注册
        isRegistered(mobile);
        // 3.判断验证码是否正确
        String key = codeType + ":" + mobile;
        SMSCodeValueInRedisDto smsCodeAndTimeFromRedis = (SMSCodeValueInRedisDto) redisTemplate.opsForValue().get(key);
        GlobalAssert.isNull(smsCodeAndTimeFromRedis, "验证码无效!");
        String smsCodeInRedis = smsCodeAndTimeFromRedis.getSmsCodeInRedis();
        GlobalAssert.isEquals(smsCode, smsCodeInRedis, "验证码错误,请重新输入!");
        // 4.保存
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        String encodedPassword = encoder.encode(password);
//        String passwordByMd5 = MD5.getMD5(password); // 密码加密
//        String salt = UUID.randomUUID().toString();
//        String passwordMd5AndSalt = passwordByMd5 + salt; // 密码加盐
        // 5.调用权限中心,保存登录信息
        LoginUser loginUser = toLoginUser(mobile, encodedPassword);
        AjaxResult result = authServiceClient.addOrUpdate(loginUser);
        GlobalAssert.isSuccess(result.isSuccess(), "注册失败,网络异常!");
        // 6.保存User
        VipUser vipUser = toVipUser(mobile, encodedPassword, result);
        baseMapper.insert(vipUser);
        // =========================测试分布式事务=============================== //
        int a = 1 / 0;

        // 7.保存vipBase
        VipBase vipBase = toVipBase(regChannel, result);
        vipBaseMapper.insert(vipBase);
    }

    // toVipBase
    private VipBase toVipBase(Integer regChannel, AjaxResult result) {
        VipBase vipBase = new VipBase();
        Date date = new Date();
        long now = date.getTime();
        vipBase.setCreateTime(now); // 设置创建时间
        vipBase.setRegChannel(regChannel); // 设置注册方式
        vipBase.setRegTime(now); // 设置注册时间
        Long loginId = Long.valueOf(result.getResultObj().toString());
        vipBase.setSsoId(loginId);
        return vipBase;
    }

    // toVipUser
    private VipUser toVipUser(String mobile, String encodedPassword, AjaxResult result) {
        VipUser vipUser = new VipUser();
        Long loginId = Long.valueOf(result.getResultObj().toString());
        Date date = new Date();
        vipUser.setCreateTime(date.getTime()); // 设置创建时间
        vipUser.setPhone(mobile); // 设置手机号
        vipUser.setPassword(encodedPassword); // 设置密码
//        vipUser.setSalt(salt); // 设置盐
        vipUser.addBitState(VipUser.BIT_STATE_PHONE); // 设置状态
        vipUser.setLoginId(loginId); // 设置loginid
        return vipUser;
    }

    // toLoginUser
    private LoginUser toLoginUser(String mobile, String encodedPassword) {
        LoginUser loginUser = new LoginUser();
        loginUser.setUsername(mobile);
        loginUser.setPassword(encodedPassword);
        loginUser.setType(USER_IN_FRONT);
        return loginUser;
    }

    // 判断手机号是否已注册
    private void isRegistered(String mobile) {
        VipUser vipUser = vipUserMapper.selectByMobile(mobile);
        if (!StringUtils.isEmpty(vipUser)) throw new GlobalException("用户已注册,请直接登录");
    }

    // 判断参数
    private void checkParam(String mobile, String password, String smsCode) {
        GlobalAssert.isValidPhoneNumber(mobile, "手机号不能为空");
        GlobalAssert.hasText(password, "密码不能为空");
        GlobalAssert.hasText(smsCode, "验证码不能为空");
    }
}
